


public class MPLgameLogic implements IGameLogic {

	    private int x = 0;
	    private int y = 0;
	    private int playerID;
	    
	    private int[][] grid;
	    
	    public MPLgameLogic() {
	        //TODO Write your implementation for this method
	    }
		
	    public void initializeGame(int x, int y, int playerID) {
	        this.x = x;
	        this.y = y;
	        this.playerID = playerID;
	        //TODO Write your implementation for this method
	        
	        // create empty grid and fill it with zeros
	        grid = new int[y][x];
	        for (int i = 0; i < grid.length; i++) {
				for (int j = 0; j < grid[i].length; j++) {
					grid[i][j] = 0;
				}
			}
	    }

	    // this method is called after both players turns
	    public void insertCoin(int column, int playerID) {
	        //TODO Write your implementation for this method
	    	
	    	// update the local board by entering the playerID
	    	// in the first available spot in given column
	    	for (int i = grid.length-1; i >= 0; i--) {
				if (grid[i][column] == 0) {
					grid[i][column] = playerID;
					printBoard();
					return;
				}
			}
	    }

	    public int decideNextMove() {
	        //TODO Write your implementation for this method
	    	
	    	// return the first non full column as next move
	    	for (int i = 0; i < grid[0].length; i++) {
				if (grid[0][i] == 0) {
							return i;
				}
	    	}
	    	return 0;
	        
	    }
	    
	    // method to print out the local board for test purposes
	    public void printBoard() {
	    	for (int i = 0; i < grid.length; i++) {
				for (int j = 0; j < grid[i].length; j++) {
					System.out.print(":" + grid[i][j]);
				}
				System.out.println();
			}
	    	System.out.println();
	    }
	    
	    /*
	    Dynamic programming gameFinished method explained: The program runs through the game
	    board from bottom to top and computes streak counts for all fields, stored in a
	    dynamic programming grid. Streak count means number of bricks on a line.
	    +---+---+---+ For a field X in the grid with a blue brick, it has:
	    |hz | X |   | hz + 1 length HORIZONTAL streak if blue brick in hz
	    +---+---+---+ vt + 1 length VERTICAL streak if blue brick in vt
	    |rd |vt |fd | rd + 1 length RISING DIAGONAL streak if blue brick in rd
	    +---+---+---+ fd + 1 length FALLING DIAGONAL streak if blue brick in fd
	     */
	    public Winner gameFinished() {
	       // A dynamic programming grid node counts the number of streaks in all 4 possible directions
	       class dp_node {
	          public int vt, hz, fd, rd;
	          public dp_node(int initial) { // Initialize all streak counters to chosen initial value
	             vt = hz = fd = rd = initial;
	          }
	          public boolean four_in_a_row() { // Returns true if one of the streak counters equals four
	             return (vt == 4 || hz == 4 || rd == 4 || fd == 4);
	          }
	       }

	       // Construct a dynamic programming grid dp_grid (of dp_nodes), remembering streaks for both player 1 and 2
	       dp_node dp_grid[][][] = new dp_node[3][y][x];

	       // Make initial grid reflect player brick positions (Steak size=1 in all directions where player has brick)
	       for (int j = 0; j < y; j++) {
	          for (int i = 0; i < x; i++) {
	             int[] player = {0, 0, 0}; // Zero for all values as default
	             player[grid[j][i]] = 1; // Streak count one in all fields for player with brick in position
	             dp_grid[1][j][i] = new dp_node(player[1]);
	             dp_grid[2][j][i] = new dp_node(player[2]);
	          }
	       }

	       // Fill the dynamic programming grid with streak values
	       for (int j = y - 1; j >= 0; j--) {
	          for (int i = 0; i < x; i++) {
	             int player = grid[j][i]; // Remember which player has brick current in slot
	             if (player == 0) continue; // If current slot is empty then skip it
	             if ((j < y - 1) && (grid[j + 1][i] == player)) // Vertical direction
	                dp_grid[player][j][i].vt = dp_grid[player][j + 1][i].vt + 1;
	             if ((i > 0) && (grid[j][i - 1] == player)) // Horizontal direction
	                dp_grid[player][j][i].hz = dp_grid[player][j][i - 1].hz + 1;
	             if ((i > 0 && j < y - 1) && (grid[j + 1][i - 1] == player)) // Rising diagonal direction
	                dp_grid[player][j][i].rd = dp_grid[player][j + 1][i - 1].rd + 1;
	             if ((j < y - 1 && i < x - 1) && (grid[j + 1][i + 1] == player)) // Falling diagonal direction
	                dp_grid[player][j][i].fd = dp_grid[player][j + 1][i + 1].fd + 1;
	          }
	       }
	       // If a player has a streak of length four, this player wins.
	       for (int j = 0; j < y; j++) {
	          for (int i = 0; i < x; i++) {
	             if (dp_grid[1][j][i].four_in_a_row()) return Winner.PLAYER1;
	             if (dp_grid[2][j][i].four_in_a_row()) return Winner.PLAYER2;
	          }
	       }
	       return Winner.NOT_FINISHED; // No winning player found, so game is not finished yet.
	    }
}
